package com.wangwei.authoritySystem.controller;

import com.wangwei.authoritySystem.common.Result;
import com.wangwei.authoritySystem.common.utils.JwtUtils;
import com.wangwei.authoritySystem.common.utils.MenuTree;
import com.wangwei.authoritySystem.config.redis.RedisService;
import com.wangwei.authoritySystem.pojo.Permission;
import com.wangwei.authoritySystem.pojo.User;
import com.wangwei.authoritySystem.pojo.UserInfo;
import com.wangwei.authoritySystem.vo.RouterVo;
import com.wangwei.authoritySystem.vo.TokenVo;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/sysUser")
public class SysUserController {
    @Autowired
    private RedisService redisService;
    @Autowired
    private JwtUtils jwtUtils;

    /**
     * 刷新token
     */
    @PostMapping("/refreshToken")
    public Result refreshToken(HttpServletRequest request){
        //从header中获取前端提交的token
        String token = request.getHeader("token");
        //如果header中没有token则从参数中获取
        if(ObjectUtils.isEmpty(token)){
            token = request.getParameter("token");
        }
        //从spring security context中获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取身份信息
        UserDetails details = (UserDetails) authentication.getPrincipal();
        //重新生成token
        String reToken="";
        //验证原来的token是否合法
        if(jwtUtils.validateToken(token,details)){
            //生成新的token
            reToken = jwtUtils.refreshToken(token);
        }
        //获取本次token到期时间交给前端做判断
        long expireTime = Jwts.parser().setSigningKey(jwtUtils.getSecret())
                .parseClaimsJws(reToken.replace("jwt_",""))
                .getBody().getExpiration().getTime();
        //清除原来token信息
        String oldTokenKey = "token_"+token;
        redisService.del(oldTokenKey);
        //存储新的token
        String newTokenkEY = "token_"+reToken;
        redisService.set(newTokenkEY,reToken,jwtUtils.getExpiration()/1000);
        //创建token vo对象
        TokenVo tokenVo = new TokenVo(expireTime,reToken);
        //返回数据
        return Result.success(200,"生成token成功",tokenVo);
    }
    //获取用户信息
    @GetMapping("/getUserInfo")
    public Result getUserInfo(){
        //从spring security context获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断authentication对象是否为空
        if(authentication == null){
            return Result.fail("用户信息查询失败");
        }
        //获取用户信息
        User user = (User) authentication.getPrincipal();
        //用户权限集合
        List<Permission> permissionList = user.getPermissionList();
        //获取角色权限编码字段
        Object[] roles = permissionList.stream()
                .filter(Objects::nonNull)
                .map(Permission::getCode).toArray();
        //创建用户信息
        UserInfo userInfo = new UserInfo(user.getId(),user.getNickName(),user.getAvatar(),null,roles);
        //返回数据
        return Result.success(200,"用户查询成功",userInfo);
    }
    @GetMapping("/getMenuList")
    public Result getMenuList(){
        //从spring security context获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断authentication对象是否为空
        if(authentication == null){
            return Result.fail("用户信息查询失败");
        }
        //获取用户信息
        User user = (User) authentication.getPrincipal();
        //用户权限集合
        List<Permission> permissionList = user.getPermissionList();
        //筛选当前用户拥有的目录和菜单数据
        List<Permission> collect = permissionList.stream()
                //0目录，1菜单，2按钮，这里排除铵钮，因为它不用放到目录菜单里
                .filter(item -> item != null && item.getType() != 2)
                .collect(Collectors.toList());
        //生成路由数据
        List<RouterVo> routerVoList = MenuTree.createRouter(collect, 0L);
        return Result.success(routerVoList);
    }

    /**
     * 退出登录
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/logout")
    public Result logout(HttpServletRequest request, HttpServletResponse response){
        //获取token信息
        String token = request.getHeader("token");
        if(ObjectUtils.isEmpty(token)){
            token = request.getParameter("token");
        }
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication !=null){
            new SecurityContextLogoutHandler().logout(request,response,authentication);
            //清除redis缓存中的token
            redisService.del("token_"+token);
            return Result.success("用户退出成功");
        }
        return Result.fail("退出失败");
    }
}



